﻿using BlockOS.ChunkStorage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace BlockOS.Client
{
    public class MainStage : AbstractClientStage
    {
        private const float UPLOAD_INTERVAL = 0.5f;

        private IWorld world;
        private ClientWorld clientWorld;

        private float uploadTimer = 0;
        public MainStage(IWorld world)
        {
            this.world = world;
        }

        public override void Init()
        {
            client.WindowManager.Clear();
            client.PushWindow("HUD");
            client.renderSurface.gameObject.SetActive(true);

            
            clientWorld = GameObject.Instantiate(client.worldPrefab);
            clientWorld.LoadStorage(new DummyStorage());
            clientWorld.Bind(world);
            clientWorld.playerCamera.targetTexture = client.Framebuffer;

            //world.UploadPlayerTransform(clientWorld.playerTransform.position, clientWorld.playerTransform.eulerAngles);
        }

        public override void Update()
        {
            uploadTimer += Time.deltaTime;
            if (uploadTimer > UPLOAD_INTERVAL)
            {
                world.UploadPlayerTransform(clientWorld.playerTransform.position, clientWorld.playerTransform.eulerAngles);
                uploadTimer = 0;
            }

            world.Update();
            foreach (var (id, entity) in world.RequestNearbyEntities())
            {
                Debug.Log($"{entity.name}({id}) update {entity.x},{entity.y},{entity.z}");
                clientWorld.UpdateEntity(id, entity);
            }
        }

        public override void Deinit()
        {
            Debug.Log("Deinit called");
            world.Deinit();
            
            clientWorld.UnloadStorage();
            clientWorld.Unbind();
            GameObject.Destroy(clientWorld.gameObject);
            client.renderSurface.gameObject.SetActive(false);
        }

        public override void OnViewportChange()
        {
            try
            {
                if (clientWorld != null && clientWorld.playerCamera != null)
                {
                    clientWorld.playerCamera.targetTexture = client.Framebuffer;
                }
            }
            catch (Exception e)
            {
                client.ShowToast(e.Message);
            }
        }
    }
}
